﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BenefitHelper.View
{
    /// <summary>
    /// 操作员月品种操作情况
    /// </summary>
    public class OperatorMonthProductInfo
    {
        public int Id { get; set; }
        public int OperatorId { get; set; }
        public virtual Sys.Operator Operator { get; set; }
        public int Year { get; set; }
        public int Month { get; set; }
        public string ProductId { get; set; }

        /// <summary>
        /// 多空方向
        /// </summary>
        public string Direction { get; set; }
        /// <summary>
        /// 盈利/亏损
        /// </summary>
        public string WinOrLost { get; set; }

        /// <summary>
        /// 平仓盈亏
        /// </summary>
        public double Profit { get; set; }
        /// <summary>
        /// 手续费
        /// </summary>
        public double Free { get; set; }
        /// <summary>
        /// 净收益
        /// </summary>
        public double DayCount { get; set; }
        /// <summary>
        /// 交易笔数
        /// </summary>
        public double BillCount { get; set; }
        /// <summary>
        /// 总亏损
        /// </summary>
        public double SumLost { get; set; }
        /// <summary>
        /// 总盈利
        /// </summary>
        public double SumWin { get; set; }
        /// <summary>
        /// 保证金占用
        /// </summary>
        public double UsedMargin { get; set; }
        /// <summary>
        /// 盈利次数
        /// </summary>
        public int WinCount { get; set; }
        /// <summary>
        /// 亏损次数
        /// </summary>
        public int LoseCount { get; set; }

        public double Percent { get; set; }

        /// <summary>
        /// 获取处理过的交易员品种交易信息(ok)
        /// </summary>
        /// <param name="tradeHistoryId"></param>
        /// <param name="operatorid"></param>
        /// <param name="db"></param>
        /// <returns></returns>
        public List<OperatorMonthProductInfo> GetSortedOperatorMonthProductInfo(int month, int year, int operatorid, DB.DBManager db)
        {
            List<OperatorMonthProductInfo> returninfos = new List<OperatorMonthProductInfo>();
            List<OperatorMonthProductInfo> infos = GetOperatorMonthProductInfo(month, year, operatorid, db);
            List<string> products = new List<string>();
            foreach (OperatorMonthProductInfo _info in infos)
            {
                var query = products.Where(t => t.Equals(_info.ProductId));
                if (query.Count() == 0)
                {
                    products.Add(_info.ProductId);
                }
            }
            foreach (string product in products)
            {
                #region 获取品种总的信息
                OperatorMonthProductInfo info = new OperatorMonthProductInfo();
                info.ProductId = product;
                info.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.BillCount);
                info.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.DayCount), 2);
                info.Direction = "-";
                info.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.Free), 2);
                info.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.LoseCount);
                info.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.Profit), 2);
                info.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.SumLost), 2);
                info.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.SumWin), 2);
                info.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.UsedMargin), 2);
                info.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Sum(a => a.WinCount);
                info.WinOrLost = "-";
                returninfos.Add(info);
                #endregion

                #region 品种多头总的情况
                OperatorMonthProductInfo info2 = new OperatorMonthProductInfo();
                info2.ProductId = product + "_#1";
                info2.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.BillCount);
                info2.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.DayCount), 2);
                info2.Direction = "多头";
                info2.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.Free), 2);
                info2.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.LoseCount);
                info2.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.Profit), 2);
                info2.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.SumLost), 2);
                info2.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.SumWin), 2);
                info2.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.UsedMargin), 2);
                info2.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Sum(a => a.WinCount);
                info2.WinOrLost = "-";
                returninfos.Add(info2);
                #endregion

                #region 品种多头 盈利 的情况
                OperatorMonthProductInfo info3 = new OperatorMonthProductInfo();
                info3.ProductId = product + "_#1";
                info3.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.BillCount);
                info3.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.DayCount), 2);
                info3.Direction = "-";
                info3.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.Free), 2);
                info3.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.LoseCount);
                info3.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.Profit), 2);
                info3.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.SumLost), 2);
                info3.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.SumWin), 2);
                info3.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.UsedMargin), 2);
                info3.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit > 0).Sum(a => a.WinCount);
                info3.WinOrLost = "盈利";
                returninfos.Add(info3);
                #endregion

                #region 品种多头 亏损 的情况
                OperatorMonthProductInfo info4 = new OperatorMonthProductInfo();
                info4.ProductId = product + "_#1";
                info4.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.BillCount);
                info4.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.DayCount), 2);
                info4.Direction = "-";
                info4.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.Free), 2);
                info4.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.LoseCount);
                info4.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.Profit), 2);
                info4.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.SumLost), 2);
                info4.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.SumWin), 2);
                info4.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.UsedMargin), 2);
                info4.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("多头")).Where(a => a.Profit < 0).Sum(a => a.WinCount);
                info4.WinOrLost = "亏损";
                returninfos.Add(info4);
                #endregion


                #region 品种空头总的情况
                OperatorMonthProductInfo info5 = new OperatorMonthProductInfo();
                info5.ProductId = product + "_#1";
                info5.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.BillCount);
                info5.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.DayCount), 2);
                info5.Direction = "空头";
                info5.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.Free), 2);
                info5.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.LoseCount);
                info5.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.Profit), 2);
                info5.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.SumLost), 2);
                info5.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.SumWin), 2);
                info5.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.UsedMargin), 2);
                info5.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Sum(a => a.WinCount);
                info5.WinOrLost = "-";
                returninfos.Add(info5);
                #endregion

                #region 品种空头 盈利 的情况
                OperatorMonthProductInfo info6 = new OperatorMonthProductInfo();
                info6.ProductId = product + "_#1";
                info6.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.BillCount);
                info6.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.DayCount), 2);
                info6.Direction = "-";
                info6.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.Free), 2);
                info6.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.LoseCount);
                info6.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.Profit), 2);
                info6.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.SumLost), 2);
                info6.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.SumWin), 2);
                info3.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.UsedMargin), 2);
                info6.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit > 0).Sum(a => a.WinCount);
                info6.WinOrLost = "盈利";
                returninfos.Add(info6);
                #endregion

                #region 品种空头 亏损 的情况
                OperatorMonthProductInfo info7 = new OperatorMonthProductInfo();
                info7.ProductId = product + "_#1";
                info7.BillCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.BillCount);
                info7.DayCount = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.DayCount), 2);
                info7.Direction = "-";
                info7.Free = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.Free), 2);
                info7.LoseCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.LoseCount);
                info7.Profit = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.Profit), 2);
                info7.SumLost = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.SumLost), 2);
                info7.SumWin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.SumWin), 2);
                info7.UsedMargin = Math.Round(infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.UsedMargin), 2);
                info7.WinCount = infos.Where(a => a.ProductId.Equals(info.ProductId)).Where(a => a.Direction.Equals("空头")).Where(a => a.Profit < 0).Sum(a => a.WinCount);
                info7.WinOrLost = "亏损";
                returninfos.Add(info7);
                #endregion


            }



            return returninfos;
        }

        /// <summary>
        /// 得到不分多空方向的品种交易信息(ok)
        /// </summary>
        /// <param name="tradeHistoryId"></param>
        /// <param name="operatorid"></param>
        /// <returns></returns>
        public List<OperatorMonthProductInfo> GetOperatorMonthProductInfoIgnoreDirection(int month, int year, int operatorid, DB.DBManager db)
        {
            List<OperatorMonthProductInfo> infos = GetOperatorMonthProductInfo(month, year, operatorid, db);
            List<OperatorMonthProductInfo> returninfos = new List<OperatorMonthProductInfo>();
            foreach (OperatorMonthProductInfo info in infos)
            {
                OperatorMonthProductInfo _info = new OperatorMonthProductInfo();
                _info.ProductId = info.ProductId;
                var query = returninfos.Where(a => a.ProductId.Equals(_info.ProductId));
                if (query.Count() > 0)
                {

                    query.First().BillCount += info.BillCount;
                    query.First().DayCount += info.DayCount;
                    query.First().Free += info.Free;
                    query.First().LoseCount += info.LoseCount;
                    query.First().Percent += info.Percent;
                    query.First().ProductId = info.ProductId;
                    query.First().Profit += info.Profit;
                    query.First().SumLost += info.SumLost;
                    query.First().SumWin += info.SumWin;
                    query.First().UsedMargin += info.UsedMargin;
                    query.First().WinCount += info.WinCount;
                    query.First().WinOrLost = info.WinOrLost;
                }
                else
                {
                    _info = info;
                    returninfos.Add(_info);
                }

            }
            return returninfos;
        }

        /// <summary>
        /// 得到分多空方向的品种交易信息(ok)
        /// </summary>
        /// <param name="tradeHistoryId"></param>
        /// <param name="operatorid"></param>
        /// <returns></returns>
        public List<OperatorMonthProductInfo> GetOperatorMonthProductInfo(int month, int year, int operatorid, DB.DBManager db)
        {
            return db.OperatorMonthProductInfo.Where(a => a.Month == month).Where(a => a.Year == year).Where(a => a.OperatorId == operatorid).ToList();
        }

        /// <summary>
        /// 得到分多空方向的品种交易信息
        /// </summary>
        /// <param name="tradeHistoryId"></param>
        /// <param name="operatorid"></param>
        /// <returns></returns>
        public void InitOperatorMonthProductInfo(int tradeHistoryId, DB.DBManager db)
        {
            var users = new Sys.Operator().GetList(db);
            Sys.TradeHistory th = new Sys.TradeHistory().GetModel(tradeHistoryId, db);
            foreach (Sys.Operator op in users)
            {
                var query = new OperatorDayProductInfo().GetOperatorDayProductInfo(tradeHistoryId, op.Id, db);
                OperatorMonthProductInfo info = new OperatorMonthProductInfo();
                foreach (OperatorDayProductInfo _info in query)
                {
                    var queryExist = db.OperatorMonthProductInfo.Where(a => a.Month == th.MPdate).Where(a => a.Year == th.YPdate).Where(a => a.OperatorId == op.Id).Where(a => a.Direction == _info.Direction).Where(a => a.ProductId.Equals(_info.ProductId)).ToList();
                    if (queryExist.Count() > 0)
                    {
                        queryExist.First().BillCount += _info.BillCount;
                        queryExist.First().DayCount += _info.DayCount;
                        queryExist.First().Free += _info.Free;
                        queryExist.First().LoseCount += _info.LoseCount;
                        queryExist.First().Percent += _info.Percent;
                        queryExist.First().ProductId += _info.ProductId;
                        queryExist.First().Profit += _info.Profit;
                        queryExist.First().SumLost += _info.SumLost;
                        queryExist.First().SumWin += _info.SumWin;
                        queryExist.First().UsedMargin += _info.UsedMargin;
                        queryExist.First().WinCount += _info.WinCount;
                        queryExist.First().WinOrLost += _info.WinOrLost;
                    }
                    else
                    {
                        info = new OperatorMonthProductInfo();
                        info.BillCount = _info.BillCount;
                        info.DayCount = _info.DayCount;
                        info.Direction = _info.Direction;
                        info.Free = _info.Free;
                        info.LoseCount = _info.LoseCount;
                        info.Month = _info.TradeHistory.MPdate;
                        info.OperatorId = _info.OperatorId;
                        info.Percent = _info.Percent;
                        info.ProductId = _info.ProductId;
                        info.Profit = _info.Profit;
                        info.SumLost = _info.SumLost;
                        info.SumWin = _info.SumWin;
                        info.UsedMargin = _info.UsedMargin;
                        info.WinCount = _info.WinCount;
                        info.WinOrLost = _info.WinOrLost;
                        info.Year = _info.TradeHistory.YPdate;
                        db.OperatorMonthProductInfo.Add(info);
                    }
                }

            }
            db.SaveChanges();
        }


        public void Delete(int tradeHistoryId, DB.DBManager db)
        {
            var Date = db.TradeHistorys.Find(tradeHistoryId);
            var query = db.OperatorMonthProductInfo.Where(a => a.Month == Date.MPdate).Where(a => a.Year == Date.YPdate).ToList();
            foreach (OperatorMonthProductInfo info in query)
            {
                db.OperatorMonthProductInfo.Remove(info);
            }
            db.SaveChanges();
        }

        public List<OperatorMonthProductInfo> GetOperatorMonthProductInfo(int month, int year, int operatorid, bool win, DB.DBManager db)
        {
            if (win)
            {
                return db.OperatorMonthProductInfo.Where(a => a.Month == month).Where(a => a.Year == year).Where(a => a.OperatorId == operatorid).Where(a => a.Profit > 0).ToList();
            }
            else
            {
                return db.OperatorMonthProductInfo.Where(a => a.Month == month).Where(a => a.Year == year).Where(a => a.OperatorId == operatorid).Where(a => a.Profit < 0).ToList();
            }
        }

    }
}
